home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / audit.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  10KB  |  371 lines

  1. #include "driver.h"
  2. #include "strings.h"
  3. #include "audit.h"
  4.  
  5.  
  6. static tAuditRecord *gAudits = NULL;
  7.  
  8.  
  9.  
  10. /* returns 1 if rom is defined in this set */
  11. int RomInSet (const struct GameDriver *gamedrv, unsigned int crc)
  12. {
  13.     const struct RomModule *romp = gamedrv->rom;
  14.  
  15.     if (!romp) return 0;
  16.  
  17.     while (romp->name || romp->offset || romp->length)
  18.     {
  19.         romp++;    /* skip ROM_REGION */
  20.  
  21.         while (romp->length)
  22.         {
  23.             if (romp->crc == crc) return 1;
  24.             do
  25.             {
  26.                 romp++;
  27.                 /* skip ROM_CONTINUEs and ROM_RELOADs */
  28.             }
  29.             while (romp->length && (romp->name == 0 || romp->name == (char *)-1));
  30.         }
  31.     }
  32.     return 0;
  33. }
  34.  
  35.  
  36. /* returns nonzero if romset is missing */
  37. int RomsetMissing (int game)
  38. {
  39.     const struct GameDriver *gamedrv = drivers[game];
  40.  
  41.     if (gamedrv->clone_of)
  42.     {
  43.         tAuditRecord    *aud;
  44.         int                count;
  45.         int             i;
  46.         int             cloneRomsFound = 0;
  47.  
  48.         if ((count = AuditRomSet (game, &aud)) == 0)
  49.             return 1;
  50.  
  51.         if (count == -1) return 0;
  52.  
  53.         /* count number of roms found that are unique to clone */
  54.         for (i = 0; i < count; i++)
  55.             if (aud[i].status != AUD_ROM_NOT_FOUND)
  56.                 if (!RomInSet (gamedrv->clone_of, aud[i].expchecksum))
  57.                     cloneRomsFound++;
  58.  
  59.         return !cloneRomsFound;
  60.     }
  61.     else
  62.         return !osd_faccess (gamedrv->name, OSD_FILETYPE_ROM);
  63. }
  64.  
  65.  
  66. /* Fills in an audit record for each rom in the romset. Sets 'audit' to
  67.    point to the list of audit records. Returns total number of roms
  68.    in the romset (same as number of audit records), 0 if romset missing. */
  69. int AuditRomSet (int game, tAuditRecord **audit)
  70. {
  71.     const struct RomModule *romp;
  72.     const char *name;
  73.     const struct GameDriver *gamedrv;
  74.  
  75.     int count = 0;
  76.     tAuditRecord *aud;
  77.     int    err;
  78.  
  79.     if (!gAudits)
  80.         gAudits = (tAuditRecord *)malloc (AUD_MAX_ROMS * sizeof (tAuditRecord));
  81.  
  82.     if (gAudits)
  83.         *audit = aud = gAudits;
  84.     else
  85.         return 0;
  86.  
  87.  
  88.     gamedrv = drivers[game];
  89.     romp = gamedrv->rom;
  90.  
  91.     if (!romp) return -1;
  92.  
  93.     /* check for existence of romset */
  94.     if (!osd_faccess (gamedrv->name, OSD_FILETYPE_ROM))
  95.     {
  96.         /* if the game is a clone, check for parent */
  97.         if (gamedrv->clone_of == 0 || (gamedrv->clone_of->flags & NOT_A_DRIVER) ||
  98.                 !osd_faccess(gamedrv->clone_of->name,OSD_FILETYPE_ROM))
  99.             return 0;
  100.     }
  101.  
  102.     while (romp->name || romp->offset || romp->length)
  103.     {
  104.         if (romp->name || romp->length) return 0; /* expecting ROM_REGION */
  105.  
  106.         romp++;
  107.  
  108.         while (romp->length)
  109.         {
  110.             const struct GameDriver *drv;
  111.  
  112.  
  113.             if (romp->name == 0)
  114.                 return 0;    /* ROM_CONTINUE not preceded by ROM_LOAD */
  115.             else if (romp->name == (char *)-1)
  116.                 return 0;    /* ROM_RELOAD not preceded by ROM_LOAD */
  117.  
  118.             name = romp->name;
  119.             strcpy (aud->rom, name);
  120.             aud->explength = 0;
  121.             aud->length = 0;
  122.             aud->expchecksum = romp->crc;
  123.             /* NS981003: support for "load by CRC" */
  124.             aud->checksum = romp->crc;
  125.             count++;
  126.  
  127.             /* obtain CRC-32 and length of ROM file */
  128.             drv = gamedrv;
  129.             do
  130.             {
  131.                 err = osd_fchecksum (drv->name, name, &aud->length, &aud->checksum);
  132.                 drv = drv->clone_of;
  133.             } while (err && drv);
  134.  
  135.             /* spin through ROM_CONTINUEs and ROM_RELOADs, totaling length */
  136.             do
  137.             {
  138.                 if (romp->name != (char *)-1) /* ROM_RELOAD */
  139.                     aud->explength += romp->length & ~ROMFLAG_MASK;
  140.                 romp++;
  141.             }
  142.             while (romp->length && (romp->name == 0 || romp->name == (char *)-1));
  143.  
  144.             if (err)
  145.             {
  146.                 if (!aud->expchecksum)
  147.                     /* not found but it's not good anyway */
  148.                     aud->status = AUD_NOT_AVAILABLE;
  149.                 else
  150.                     /* not found */
  151.                     aud->status = AUD_ROM_NOT_FOUND;
  152.             }
  153.             /* all cases below assume the ROM was at least found */
  154.             else if (aud->explength != aud->length)
  155.                 aud->status = AUD_LENGTH_MISMATCH;
  156.             else if (aud->checksum != aud->expchecksum)
  157.             {
  158.                 if (!aud->expchecksum)
  159.                     aud->status = AUD_ROM_NEED_DUMP; /* new case - found but not known to be dumped */
  160.                 else if (aud->checksum == BADCRC (aud->expchecksum))
  161.                     aud->status = AUD_ROM_NEED_REDUMP;
  162.                 else
  163.                     aud->status = AUD_BAD_CHECKSUM;
  164.             }
  165.             else
  166.                 aud->status = AUD_ROM_GOOD;
  167.  
  168.             aud++;
  169.         }
  170.     }
  171.  
  172.         #ifdef MESS
  173.         if (!count)
  174.                 return -1;
  175.         else
  176.         #endif
  177.     return count;
  178. }
  179.  
  180.  
  181. /* Generic function for evaluating a romset. Some platforms may wish to
  182.    call AuditRomSet() instead and implement their own reporting (like MacMAME). */
  183. int VerifyRomSet (int game, verify_printf_proc verify_printf)
  184. {
  185.     tAuditRecord            *aud;
  186.     int                        count;
  187.     int                        archive_status = 0;
  188.     const struct GameDriver *gamedrv = drivers[game];
  189.  
  190.     if ((count = AuditRomSet (game, &aud)) == 0)
  191.         return NOTFOUND;
  192.  
  193.     if (count == -1) return CORRECT;
  194.  
  195.         if (gamedrv->clone_of)
  196.     {
  197.         int i;
  198.         int cloneRomsFound = 0;
  199.  
  200.         /* count number of roms found that are unique to clone */
  201.         for (i = 0; i < count; i++)
  202.             if (aud[i].status != AUD_ROM_NOT_FOUND)
  203.                 if (!RomInSet (gamedrv->clone_of, aud[i].expchecksum))
  204.                     cloneRomsFound++;
  205.  
  206.                 #ifndef MESS
  207.                 /* Different MESS systems can use the same ROMs */
  208.         if (cloneRomsFound == 0)
  209.             return CLONE_NOTFOUND;
  210.                 #endif
  211.     }
  212.  
  213.     while (count--)
  214.     {
  215.         archive_status |= aud->status;
  216.  
  217.         switch (aud->status)
  218.         {
  219.             case AUD_ROM_NOT_FOUND:
  220.                 verify_printf ("%-8s: %-12s %7d bytes %08x NOT FOUND\n",
  221.                     drivers[game]->name, aud->rom, aud->explength, aud->expchecksum);
  222.                 break;
  223.             case AUD_NOT_AVAILABLE:
  224.                 verify_printf ("%-8s: %-12s %7d bytes NOT FOUND - NO GOOD DUMP KNOWN\n",
  225.                     drivers[game]->name, aud->rom, aud->explength);
  226.                 break;
  227.             case AUD_ROM_NEED_DUMP:
  228.                 verify_printf ("%-8s: %-12s %7d bytes NO GOOD DUMP KNOWN\n",
  229.                     drivers[game]->name, aud->rom, aud->explength);
  230.                 break;
  231.             case AUD_BAD_CHECKSUM:
  232.                 verify_printf ("%-8s: %-12s %7d bytes %08x INCORRECT CHECKSUM: %08x\n",
  233.                     drivers[game]->name, aud->rom, aud->explength, aud->expchecksum,aud->checksum);
  234.                 break;
  235.             case AUD_ROM_NEED_REDUMP:
  236.                 verify_printf ("%-8s: %-12s %7d bytes ROM NEEDS REDUMP\n",
  237.                     drivers[game]->name, aud->rom, aud->explength);
  238.                 break;
  239.             case AUD_MEM_ERROR:
  240.                 verify_printf ("Out of memory reading ROM %s\n", aud->rom);
  241.                 break;
  242.             case AUD_LENGTH_MISMATCH:
  243.                 verify_printf ("%-8s: %-12s %7d bytes %08x INCORRECT LENGTH: %8d\n",
  244.                     drivers[game]->name, aud->rom, aud->explength, aud->expchecksum,aud->length);
  245.                 break;
  246.             case AUD_ROM_GOOD:
  247. #if 0    /* if you want a full accounting of roms */
  248.                 verify_printf ("%-8s: %-12s %7d bytes %08x ROM GOOD\n",
  249.                     drivers[game]->name, aud->rom, aud->explength, aud->expchecksum);
  250. #endif
  251.                 break;
  252.         }
  253.         aud++;
  254.     }
  255.  
  256.     if (archive_status & (AUD_ROM_NOT_FOUND|AUD_BAD_CHECKSUM|AUD_MEM_ERROR|AUD_LENGTH_MISMATCH))
  257.         return INCORRECT;
  258.     if (archive_status & (AUD_ROM_NEED_DUMP|AUD_ROM_NEED_REDUMP|AUD_NOT_AVAILABLE))
  259.         return BEST_AVAILABLE;
  260.  
  261.     return CORRECT;
  262.  
  263. }
  264.  
  265.  
  266. static tMissingSample *gMissingSamples = NULL;
  267.  
  268. /* Builds a list of every missing sample. Returns total number of missing
  269.    samples, or -1 if no samples were found. Sets audit to point to the
  270.    list of missing samples. */
  271. int AuditSampleSet (int game, tMissingSample **audit)
  272. {
  273.     int skipfirst;
  274.     void *f;
  275.     const char **samplenames, *sharedname;
  276.     int exist;
  277.     static const struct GameDriver *gamedrv;
  278.     int j;
  279.     int count = 0;
  280.     tMissingSample *aud;
  281.  
  282.     gamedrv = drivers[game];
  283.     samplenames = NULL;
  284. #if (HAS_SAMPLES)
  285.     for( j = 0; gamedrv->drv->sound[j].sound_type && j < MAX_SOUND; j++ )
  286.     {
  287.         if( gamedrv->drv->sound[j].sound_type == SOUND_SAMPLES )
  288.             samplenames = ((struct Samplesinterface *)gamedrv->drv->sound[j].sound_interface)->samplenames;
  289.     }
  290. #endif
  291.     /* does the game use samples at all? */
  292.     if (samplenames == 0 || samplenames[0] == 0)
  293.         return 0;
  294.  
  295.     /* take care of shared samples */
  296.     if (samplenames[0][0] == '*')
  297.     {
  298.         sharedname=samplenames[0]+1;
  299.         skipfirst = 1;
  300.     }
  301.     else
  302.     {
  303.         sharedname = NULL;
  304.         skipfirst = 0;
  305.     }
  306.  
  307.     /* do we have samples for this game? */
  308.     exist = osd_faccess (gamedrv->name, OSD_FILETYPE_SAMPLE);
  309.  
  310.     /* try shared samples */
  311.     if (!exist && skipfirst)
  312.         exist = osd_faccess (sharedname, OSD_FILETYPE_SAMPLE);
  313.  
  314.     /* if still not found, we're done */
  315.     if (!exist)
  316.         return -1;
  317.  
  318.     /* allocate missing samples list (if necessary) */
  319.     if (!gMissingSamples)
  320.         gMissingSamples = (tMissingSample *)malloc (AUD_MAX_SAMPLES * sizeof (tMissingSample));
  321.  
  322.     if (gMissingSamples)
  323.         *audit = aud = gMissingSamples;
  324.     else
  325.         return 0;
  326.  
  327.     for (j = skipfirst; samplenames[j] != 0; j++)
  328.     {
  329.         /* skip empty definitions */
  330.         if (strlen (samplenames[j]) == 0)
  331.             continue;
  332.         f = osd_fopen (gamedrv->name, samplenames[j], OSD_FILETYPE_SAMPLE, 0);
  333.         if (f == NULL && skipfirst)
  334.             f = osd_fopen (sharedname, samplenames[j], OSD_FILETYPE_SAMPLE, 0);
  335.  
  336.         if (f)
  337.             osd_fclose(f);
  338.         else
  339.         {
  340.             strcpy (aud->name, samplenames[j]);
  341.             count++;
  342.             aud++;
  343.         }
  344.     }
  345.     return count;
  346. }
  347.  
  348.  
  349. /* Generic function for evaluating a sampleset. Some platforms may wish to
  350.    call AuditSampleSet() instead and implement their own reporting (like MacMAME). */
  351. int VerifySampleSet (int game, verify_printf_proc verify_printf)
  352. {
  353.     tMissingSample    *aud;
  354.     int                count;
  355.  
  356.     count = AuditSampleSet (game, &aud);
  357.     if (count==-1)
  358.         return NOTFOUND;
  359.     else if (count==0)
  360.         return CORRECT;
  361.  
  362.     /* list missing samples */
  363.     while (count--)
  364.     {
  365.         verify_printf ("%-8s: %s NOT FOUND\n", drivers[game]->name, aud->name);
  366.         aud++;
  367.     }
  368.  
  369.     return INCORRECT;
  370. }
  371.